package com.cndw.kungfu.model.task;

import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.cndw.kungfu.config.ConstantsConfig;
import com.cndw.kungfu.config.ConstantsDayIntKey;
import com.cndw.kungfu.config.ConstantsIntKey;
import com.cndw.kungfu.config.ConstantsModel;
import com.cndw.kungfu.config.ConstantsRadio;
import com.cndw.kungfu.config.ConstantsTask;
import com.cndw.kungfu.core.cache.CacheTask;
import com.cndw.kungfu.domain.Npc;
import com.cndw.kungfu.domain.Player;
import com.cndw.kungfu.domain.Task;
import com.cndw.kungfu.domain.TaskMode;
import com.cndw.kungfu.ext.LogUtil;
import com.cndw.kungfu.model.Context;
import com.cndw.kungfu.model.goods.PlayerBoxs;
import com.cndw.kungfu.model.skill.PlayerSkill;
import com.cndw.kungfu.vo.TaskConditionVO;
import com.cndw.kungfu.vo.TaskVO;
import com.cndw.kungfu.vo.goodsvo.GoodsVO;

/**
 * 执行任务记录的接口
 * 
 * @author fantadust
 * @date 下午04:08:20
 */

@Service
public class TaskServer {
	@Autowired
	private CacheTask cacheTask;
	@Autowired
	private TaskManager taskManager;
	private static final int refreshSeconds = 2;

	public Collection<TaskMode> getAllSecrets() {
		return cacheTask.getAllSecrets();
	}

	@Deprecated
	public TaskMode geTaskMode(int taskId) {
		return taskManager.getModeById(taskId);
	}

	// 在任务列表改变状态后更新需要监视的操作列表.避免不必要的检查.浪费资源

	public PlayerTasks getPlayerTasks(long playerId) {
		return taskManager.getPlayerTasksById(playerId);
	}

	public void checkAwaitSecret(long playerId) {
		PlayerTasks playerTasks = getPlayerTasks(playerId);
		if (playerTasks.getAwaitSecretId() > 0) {
			TaskMode taskMode = taskManager.getModeById(playerTasks.getAwaitSecretId());
			boolean isReached = taskManager.checkIsReached(playerId, taskMode);
			if (isReached) {
				playerTasks.changeIds.add(playerTasks.getAwaitSecretId());
				playerTasks.setAwaitSecretId(0);
			}
		}
	}

	public void gcTaskProgress(long playerId) {
		PlayerTasks playerTasks = getPlayerTasks(playerId);
		playerTasks.gcTaskProgress();
	}

	/**
	 * 记录玩家杀怪数量
	 */
	public void killMonsterToTask(long playerId, List<Integer> monsterIds) {
		if (monsterIds == null || monsterIds.size() < 1) {
			return;
		}
		Map<Integer, Integer> idsMap = new HashMap<Integer, Integer>(monsterIds.size());
		for (Integer monsterId : monsterIds) {
			int num = idsMap.containsKey(monsterId) ? idsMap.get(monsterId) + 1 : 1;
			idsMap.put(monsterId, num);
		}
		for (Map.Entry<Integer, Integer> entry : idsMap.entrySet()) {
			notifyToSpark(playerId, entry.getKey(), entry.getValue());
		}

	}

	/**
	 * 触发性事件通知
	 * 
	 * @param playerId
	 * @param signId
	 * @param num
	 */
	public void notifyToSpark(long playerId, int signId, int num) {
		PlayerTasks playerTasks = getPlayerTasks(playerId);
		Set<Integer> taskIds = playerTasks.overseeGet(signId);
		if (taskIds == null) {
			return;
		}
		for (Integer taskId : taskIds) {
			int finalNum = num;
			Map<Integer, Integer> sparkMap = playerTasks.getProgressByTaskId(taskId).getSparkMap();
			if (sparkMap.containsKey(signId)) {
				finalNum = sparkMap.get(signId) + num;
			}
			sparkMap.put(signId, finalNum);
		}
		sparkOverseeTask(playerId, signId);
	}

	/**
	 * 收集信息到怪物
	 * 
	 * @param playerId
	 * @param goodsId
	 */
	public void sparkOverseeTask(long playerId, int signId) {
		PlayerTasks playerTasks = getPlayerTasks(playerId);
		Set<Integer> taskIds = playerTasks.overseeGet(signId);
		if (taskIds == null) {
			return;
		}
		Iterator<Integer> iterator = taskIds.iterator();
		while (iterator.hasNext()) {
			Integer taskId = (Integer) iterator.next();
			TaskMode mode = taskManager.getModeById(taskId);
			if (mode == null) {
				iterator.remove();
				continue;
			}

			if (mode.isTypeIntent() && playerTasks.checkDoneOnce(taskId)) {

			} else if (!mode.isTypeIntent() && !mode.isTypeSecret() && playerTasks.isDoing(taskId) == false) {
				iterator.remove();
			}
		}
		if (taskIds == null || taskIds.isEmpty()) {
			playerTasks.overseeRemove(signId);
		} else {
			playerTasks.changeIds.addAll(taskIds);
			autoRaidioTask(playerId, refreshSeconds);
		}

	}

	/**
	 * 自动广播发生改变的任务列表
	 * 
	 * @param playerId
	 * @param seconds
	 */
	public void autoRaidioTask(long playerId, int seconds) {
		try {
			PlayerTasks playerTasks = taskManager.getPlayerTasksById(playerId);
			taskManager.checkTaskStatus(playerId);
			playerTasks.refreshTaskModes();
			Set<Integer> changeIds = playerTasks.changeIds;
			if (changeIds.size() > 0) {
				Integer[] ids = changeIds.toArray(new Integer[changeIds.size()]);
				List<TaskVO> list = toTaskVO(playerId, false, ids);
				playerTasks.changeIds.clear();
				if (list == null || list.isEmpty()) {
					return;
				}
				Context.getTcpServer().broadcast(list, ConstantsRadio.TASKLIST, playerId);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}

	}

	/**
	 * 给指定id的任务转换成vo
	 * 
	 * @param playerId
	 * @param taskIds
	 * @return
	 */
	public List<TaskVO> toTaskVO(Long playerId, Boolean isIntent, Integer... taskIds) {
		Player player = Context.getPlayerServer().getByPlayerId(playerId);

		PlayerTasks playerTasks = getPlayerTasks(playerId);
		List<TaskVO> list = new LinkedList<TaskVO>();

		if (taskIds == null) {
			return null;
		}
		for (Integer taskId : taskIds) {
			if (taskId == null) {
				continue;
			}
			TaskMode taskMode = taskManager.getModeById(taskId);
			if (taskMode == null) {
				continue;
			}
			TaskVO taskVO = new TaskVO(taskMode);

			boolean isDoing = false;
			if (playerTasks.isDoing(taskId)) {
				Task taskTemp = playerTasks.geTask(taskId);
				taskVO.setId(taskTemp.getId());
				taskVO.setStatus(taskTemp.getStatus());
				taskVO.setQuality(taskTemp.getQuality());
				if (taskMode.isSpecialType()) {
					int overTimes = player.getDataInfo().getEveryDay().getTaskTimes(taskMode.getType());
					taskVO.setOverTimes(overTimes);
				}

				isDoing = true;
			} else {
				if (playerTasks.currentCanDo(taskId)) {
					taskVO.setStatus(Task.STATUS_CANACCEPT);
				}
			}
			if (taskMode.isTypeSecret()) {// 只检测秘典任务,目标任务不检测
				isDoing = true;
				if (playerTasks.checkDoneOnce(taskId)) {
					isDoing = false;
					taskVO.setStatus(Task.STATUS_END);
				}
			}

			if (taskMode.getTaskConditionsList() != null) {
				List<TaskConditionVO> taskConditionsList = new LinkedList<TaskConditionVO>();
				boolean isTempOk = true;
				for (TaskCondition e : taskMode.getTaskConditionsList()) {
					TaskConditionVO ev = new TaskConditionVO(e);
					if (e.isDetect() && e.getTargerId() == ConstantsTask.detect10ChallengeDream) {
						ev.count = 1;
					}
					if (taskVO.getStatus() == Task.STATUS_FINISH || taskVO.getStatus() == Task.STATUS_END) {
						// 外部完成
						ev.havaCount = ev.count;
					} else if (taskVO.getStatus() == Task.STATUS_DOING || taskMode.isTypeSecret()) {
						ev.havaCount = getTaskCompletion(playerId, e, taskId);
					}
					ev.havaCount = ev.havaCount > ev.count ? ev.count : ev.havaCount;
					ev.suc = ev.havaCount >= ev.count;
					if (ev.suc == false) {
						isTempOk = false;
						if (taskMode.isTypeSecret() && playerTasks.getAwaitSecretId() != taskId) {
							playerTasks.setAwaitSecretId(taskId);// 把任务检测加入记录
						}
					}

					if ((e.isCollectGoods() || e.isSpark() || e.isKill()) && ev.suc == false && isDoing) {// 添加监控
						playerTasks.overseeAdd(e.getTargerId(), taskId);
					}
					if (ev.suc && playerTasks.overseeConstins(e.getTargerId())) {
						Set<Integer> seeIds = playerTasks.overseeGet(e.getTargerId());
						if (seeIds != null) {
							if (seeIds.size() > 1) {// 清理
								seeIds.remove(taskMode.getTaskId());
							} else {
								playerTasks.overseeRemove(e.getTargerId());
							}
						}
					}

					taskConditionsList.add(ev);
				}
				taskVO.setTaskConditionsList(taskConditionsList);

				if (isTempOk && isDoing) {
					taskVO.setStatus(Task.STATUS_FINISH);
				}
			}
			if (!isIntent && taskMode.isTypeIntent()) {
				continue;// 目標任務不增加列表
			}
			/**
			 * 清理掉不是自己职业的道具
			 */
			if (taskVO.getChooseAwards() != null) {
				Iterator<GoodsVO> iterator = taskVO.getChooseAwards().iterator();
				while (iterator.hasNext()) {
					GoodsVO goodsVO = (GoodsVO) iterator.next();
					try {
						int xxxVId = goodsVO.getGoodsModeVO().getVocationId();
						if (xxxVId > 0 && xxxVId != player.getVocationId()) {
							iterator.remove();
						}
					} catch (Exception e) {
						e.printStackTrace();
					}
				}
			}

			Npc npc = Context.getSceneServer().getNpcById(taskMode.getSourceNpcId());
			if (npc != null) {
				taskVO.setSourceNpcName(npc.getName());
			}
			npc = Context.getSceneServer().getNpcById(taskMode.getTargetNpcId());
			if (npc != null) {
				taskVO.setTargetNpcName(npc.getName());
			}
			list.add(taskVO);
		}

		return list;
	}

	/**
	 * 返回任务某个条件的完成状态
	 * 
	 * @param playerId
	 * @param tce
	 * @return
	 */
	public int getTaskCompletion(long playerId, TaskCondition tce, int taskId) {
		PlayerTasks playerTasks = taskManager.getPlayerTasksById(playerId);
		if (tce.isCollectGoods()) {// 收集类任务查数量
			PlayerBoxs playerBoxs = Context.getPlayerServer().getByPlayerId(playerId).getPlayerBoxs();
			return playerBoxs.getStackNum(tce.getTargerId());
		} else if (tce.isSpark() || tce.isKill()) {
			Map<Integer, Integer> sparkMap = playerTasks.getProgressByTaskId(taskId).getSparkMap();
			if (sparkMap != null && sparkMap.containsKey(tce.getTargerId())) {
				return sparkMap.get(tce.getTargerId());
			} else {
				switch (tce.getTargerId()) {
				case ConstantsTask.spark2EquipInstall:
					PlayerBoxs playerBoxs = Context.getPlayerServer().getByPlayerId(playerId).getPlayerBoxs();
					return playerBoxs.getEquipList().size();
				case ConstantsTask.spark5SkillUpgrade:
					PlayerSkill playerSkill = Context.getSkillServer().getPlayerSkill(playerId);
					if (playerSkill != null && playerSkill.getSkillMap().size() > 0) {
						return 1;
					}
					return 0;
				default:
					break;
				}
			}
			return 0;
		} else if (tce.isDetect()) {
			Player player = Context.getPlayerServer().getByPlayerId(playerId);
			switch (tce.getTargerId()) {
			case ConstantsTask.detect1PlayerLevel:
				return player.getLevel();
			case ConstantsTask.detect2FriendsNums:
				return player.getDataInfo().getFriendIds().size();
			case ConstantsTask.detect3AddUnion:
				if (player.getUnionId() > 0) {
					return 1;
				}
				break;
			case ConstantsTask.detect4AttackAchieve:
				return player.getAttack();
			case ConstantsTask.detect5DefenseAchieve:
				return player.getDefense();
			case ConstantsTask.detect7QuizScoreAchieve:
				return player.getDataInfo().intDataGet(ConstantsIntKey.quizScore);
			case ConstantsTask.detect8DiscipleAchieve:
				return Context.getDiscipleServer().getByPlayerId(playerId).getDisciples().size();
			case ConstantsTask.detect9TaskComplete:
				if (playerTasks.checkDoneOnce(tce.getCount())) {
					return tce.getCount();
				} else {
					return 0;
				}
			case ConstantsTask.detect10ChallengeDream:
				if (player.getDataInfo().intDataGet(ConstantsIntKey.dreamId) >= tce.getCount()) {
					return tce.getCount();
				} else {
					return 0;
				}
			default:
				break;
			}
		}
		return 0;
	}

	/**
	 * 检查还需要掉落
	 * 
	 * @param playerId
	 * @param taskId
	 * @param goodsId
	 * @return
	 */
	public boolean checkNeedFail(long playerId, int taskId, int goodsId) {
		if (taskId == 0) {
			return true;
		}
		PlayerTasks playerTasks = getPlayerTasks(playerId);
		Task task = playerTasks.geTask(taskId);
		if (task != null && task.getStatus() == Task.STATUS_DOING) {
			TaskMode taskMode = taskManager.getModeById(taskId);
			if (taskMode == null || taskMode.getTaskConditionsList() == null) {
				LogUtil.getMain().error("err need " + taskId + " |" + goodsId);
				return false;
			}
			for (TaskCondition e : taskMode.getTaskConditionsList()) {
				if (e.getTargerId() == goodsId) {
					if (getTaskCompletion(playerId, e, taskId) < e.getCount()) {
						return true;
					}
				}
			}
		}
		return false;
	}

	/**
	 * 獲取今天任务剩余次数
	 * 
	 * @param playerId
	 * @param type
	 * @return
	 */
	public int getTaskLaveTimes(long playerId, int type) {
		Player player = Context.getPlayerServer().getByPlayerId(playerId);
		int maxAcceptTimes = 0;
		if (type == TaskMode.typePrestige) {
			maxAcceptTimes = ConstantsConfig.getTaskDayNumsPrestige();
			// if (player.getVipLevel() > 0) {
			// maxAcceptTimes += player.getVip().getTaskPrestigeTimes();
			// }
		} else if (type == TaskMode.typeUnionCycle) {
			maxAcceptTimes = ConstantsConfig.getTaskDayNumsUnion();
		} else if (type == TaskMode.typeDaily) {
			maxAcceptTimes = ConstantsConfig.getTaskDayNumsDaily();
		} else if (type == TaskMode.typeDart) {
			maxAcceptTimes = ConstantsConfig.getTaskDayNumsDart();
			if (player.getKnight() != null && player.getKnight().isOpenVipDart()) {
				maxAcceptTimes += 1;
			}
		}
		int laveTimes = maxAcceptTimes - player.getDataInfo().getEveryDay().getTaskTimes(type);
		return laveTimes;
	}

	public int getTaskDartKillTime(Player player) {
		return ConstantsModel.taskDartKillNum + player.getDataInfo().getEveryDay().intDataGet(ConstantsDayIntKey.dartKB)
				- player.getDataInfo().getEveryDay().intDataGet(ConstantsDayIntKey.dartKill);
	}

	public int checkPrestigeDouble(int accept, int submit) {
		int coefficient = 1;
		int begin1 = ConstantsModel.taskDouble1Begin;
		int end1 = ConstantsModel.taskDouble1End;
		int begin2 = ConstantsModel.taskDouble2Begin;
		int end2 = ConstantsModel.taskDouble2End;
		accept = accept % 86400 + 28800;
		submit = submit % 86400 + 28000;

		if (accept > 0) {
			if (accept >= begin1 && accept <= end1) {
				coefficient++;
			} else if (accept >= begin2 && accept <= end2) {
				coefficient++;
			}
		}
		if (submit > 0) {
			if (submit >= begin1 && submit <= end1) {
				coefficient++;
			} else if (submit >= begin2 && submit <= end2) {
				coefficient++;
			}
		}

		return coefficient;
	}

}
